home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************
- µCinema Converter 1.0
- module: PICS to QuickTime.c
- February 1994 - April 1994
- by John A. Schlack
- *********************************************************************************/
-
-
- #include <Movies.h>
- #include <Script.h>
-
- #include "constants.h"
- #include "PICS to QuickTime.h"
- #include "preferences.h"
- #include "pstring.h"
- #include "µCinema.h"
-
-
- /* --------------------------------------------------------------------------------- */
-
-
- #define BASE_PICT_INDEX 128
-
-
- /* --------------------------------------------------------------------------------- */
-
-
- typedef struct pics_info
- {
- short bwColor; // 0 = BW, 1 = color
- short depth; // bits per pixel
- short speed; // frames per second ???
- short version; // set to 0
- OSType creator;
- long maxFrame; // maximum frame size
- } pics_info;
-
-
- /* --------------------------------------------------------------------------------- */
-
-
- static pics_info rPICSInfo;
- static short basePictIndex;
-
-
- /* --------------------------------------------------------------------------------- */
-
-
- static void picsToMovie( FSSpec * picsFile, FSSpec * movieFile );
- static void CreateMyVideoTrack( Movie theMovie, FSSpec * spec );
- static void AddVideoSamples( Media theMedia, Rect * trackFrame, long max,
- unsigned char * picsFileName );
- static void DrawMyFrame( Rect * trackFrame, short id );
- static Boolean inputFileValid( FSSpec * picsFile, Boolean interactive );
- static void buildName( unsigned char * newBaseName, unsigned char * variant );
-
-
- /* --------------------------------------------------------------------------------- */
-
-
- void picsToMovieBatch( FSSpec * picsFile )
- {
- FSSpec movieFile;
- Str63 tempName;
- long attempts;
- short fileRefNo;
-
- if (!inputFileValid( picsFile, false ))
- return;
-
- /* build file name, if file with duplicate name present, try a new name */
-
- movieFile = *picsFile;
- pstrcpy( tempName, movieFile.name );
- buildName( tempName, movieFile.name );
- for (attempts=0L; attempts<1000L; attempts++)
- {
- if (FSpOpenRF( &movieFile, fsRdPerm, &fileRefNo ) != noErr)
- break;
- FSClose( fileRefNo );
- buildName( nil, movieFile.name );
- }
-
- /* abort if failed to find new name after great number of attempts */
-
- if (attempts >= 1000L)
- {
- errorHandlerParameter( ERR_INPUT_FILE, picsFile->name );
- return;
- }
-
- /* convert the file */
-
- picsToMovie( picsFile, &movieFile );
- }
-
-
- /* --------------------------------------------------------------------------------- */
-
-
- void picsToMovieInteractive( void )
- {
- Str63 tempName;
- SFTypeList typelist;
- StandardFileReply getreply, putreply;
-
- typelist[0] = 'PICS';
- StandardGetFile(nil, 1, typelist, &getreply);
- if (!getreply.sfGood)
- return;
-
- if (!inputFileValid( &getreply.sfFile, true ))
- return;
-
- buildName( getreply.sfFile.name, tempName );
- StandardPutFile("\pSave movie as:", tempName, &putreply);
- if (!putreply.sfGood)
- return;
-
- picsToMovie( &getreply.sfFile, &putreply.sfFile );
- }
-
-
- /* --------------------------------------------------------------------------------- */
-
-
- static void picsToMovie( FSSpec * picsFile, FSSpec * movieFile )
- {
- Movie theMovie = nil;
- OSErr err = noErr;
- short saveref, resRefNum = 0, resId = 0;
-
- saveref = CurResFile();
- err = EnterMovies();
-
- err = CreateMovieFile( movieFile, 'SPLY', smCurrentScript, createMovieFileDeleteCurFile,
- &resRefNum, &theMovie );
- CreateMyVideoTrack( theMovie, picsFile );
- err = AddMovieResource( theMovie, resRefNum, &resId, movieFile->name );
- if (resRefNum)
- CloseMovieFile( resRefNum );
-
- UseResFile(saveref);
- ExitMovies();
- }
-
-
- /* --------------------------------------------------------------------------------- */
-
-
- static void CreateMyVideoTrack( Movie theMovie, FSSpec * spec )
- {
- Str255 dummyName;
- ResType dummyType;
- Track theTrack;
- Media theMedia;
- OSErr err = noErr;
- Rect trackFrame = { 0, 0, 160, 120 };
- Handle myres;
- short resfile, max;
-
- resfile = FSpOpenResFile( spec, fsRdPerm );
- if (resfile == -1)
- {
- errorHandlerParameter( ERR_INPUT_FILE, spec->name );
- return;
- }
- UseResFile( resfile );
-
- max = Count1Resources( 'PICT' );
- if (max <= 0)
- {
- errorHandlerParameter( ERR_PICS_DATA, spec->name );
- return;
- }
-
- /*
- Attempt to get first PICT data item. The default is index 128. If it is
- not there, get first PICT item. Abort if item index is less than 128.
- */
- basePictIndex = BASE_PICT_INDEX;
- myres = Get1Resource( 'PICT', basePictIndex );
- if (myres == NULL)
- {
- myres = Get1IndResource( 'PICT', 1 );
- if (myres != NULL)
- {
- GetResInfo( myres, &basePictIndex, &dummyType, dummyName );
- if (basePictIndex < BASE_PICT_INDEX)
- {
- ReleaseResource( myres );
- myres = nil;
- }
- }
- }
-
- if (myres == nil)
- {
- errorHandlerParameter( ERR_PICS_DATA, spec->name );
- return;
- }
- LoadResource( myres );
- trackFrame = (**((PicHandle) myres)).picFrame;
- ReleaseResource( myres );
-
- theTrack = NewMovieTrack( theMovie, FixRatio( trackFrame.right, 1 ),
- FixRatio( trackFrame.bottom, 1 ), kNoVolume );
- err = GetMoviesError();
-
- theMedia = NewTrackMedia( theTrack, VideoMediaType, rPICSInfo.speed, NULL, 0 );
- err = GetMoviesError();
-
- err = BeginMediaEdits( theMedia );
- AddVideoSamples( theMedia, &trackFrame, (long) max, spec->name );
- err = EndMediaEdits( theMedia );
-
- err = InsertMediaIntoTrack( theTrack, 0, 0, GetMediaDuration( theMedia ), 0x00010000L );
- }
-
-
- /* --------------------------------------------------------------------------------- */
-
-
- static void AddVideoSamples( Media theMedia, Rect * trackFrame, long max,
- unsigned char * picsFileName )
- {
- long maxCompressedSize;
- GWorldPtr theGWorld;
- long curSample;
- Handle compressedData = nil;
- Ptr compressedDataPtr;
- ImageDescriptionHandle imageDesc = nil;
- CGrafPtr oldPort;
- GDHandle oldGDeviceH;
- OSErr err = noErr;
- short j;
-
- err = NewGWorld( &theGWorld, 8 /* depth */, trackFrame, nil, nil, (GWorldFlags) 0 );
- LockPixels( theGWorld->portPixMap );
- err = GetMaxCompressionSize( theGWorld->portPixMap, trackFrame, 0,
- codecNormalQuality, 'rle ', (CompressorComponent) anyCodec,
- &maxCompressedSize );
-
- compressedData = NewHandle( maxCompressedSize );
- if (MemError())
- {
- errorHandlerParameter( ERR_MEMORY, picsFileName );
- return;
- }
- MoveHHi( compressedData );
- HLock( compressedData );
- compressedDataPtr = StripAddress( *compressedData );
-
- imageDesc = (ImageDescriptionHandle) NewHandle( 4L );
- if (MemError())
- {
- errorHandlerParameter( ERR_MEMORY, picsFileName );
- return;
- }
-
- GetGWorld( &oldPort, &oldGDeviceH );
- SetGWorld( theGWorld, nil );
-
- for (curSample=0L, j=basePictIndex; curSample<max; curSample++, j++)
- {
- EraseRect( trackFrame );
- DrawMyFrame( trackFrame, j );
-
- err = CompressImage( theGWorld->portPixMap, trackFrame, codecNormalQuality,
- 'rle ', imageDesc, compressedDataPtr );
- err = AddMediaSample( theMedia, compressedData, 0, (**imageDesc).dataSize,
- 1, (SampleDescriptionHandle) imageDesc, 1, 0, nil );
- }
-
- SetGWorld( oldPort, oldGDeviceH );
- if (imageDesc != NULL)
- DisposeHandle( (Handle) imageDesc );
- if (compressedData != NULL)
- DisposeHandle( compressedData );
- if (theGWorld != NULL)
- DisposeGWorld( theGWorld );
- }
-
-
- /* --------------------------------------------------------------------------------- */
-
-
- static void DrawMyFrame( Rect * trackFrame, short id )
- {
- Handle pict;
-
- pict = Get1Resource( 'PICT', id );
- if (pict == nil)
- return;
- LoadResource( pict );
- DrawPicture( (PicHandle) pict, trackFrame );
- ReleaseResource( pict );
- }
-
-
- /* --------------------------------------------------------------------------------- */
-
-
- static Boolean inputFileValid( FSSpec * picsFile, Boolean interactive )
- /*
- Checks to see that the file if of type 'PICS'. Also, checks loads the PICS info
- resource. If not found, dialog displayed if interactive, else, preferences
- value is used.
- */
- {
- FInfo info;
- Handle picsInfo;
- short saveref, resfile;
- Boolean infoValid = false;
-
- if (FSpGetFInfo( picsFile, &info) != noErr)
- {
- errorHandlerParameter( ERR_INPUT_FILE, picsFile->name );
- return false;
- }
- if (info.fdType != 'PICS')
- {
- errorHandlerParameter( ERR_NOT_PICS, picsFile->name );
- return false;
- }
-
- saveref = CurResFile();
- resfile = FSpOpenResFile( picsFile, fsRdPerm );
- if (resfile == -1)
- {
- errorHandlerParameter( ERR_INPUT_FILE, picsFile->name );
- return false;
- }
- picsInfo = Get1Resource( 'INFO', 128 );
- if (picsInfo != nil)
- {
- if (SizeResource( picsInfo ) == sizeof( pics_info ))
- {
- LoadResource( picsInfo );
- HLock( picsInfo );
- BlockMove( *picsInfo, &rPICSInfo, sizeof( rPICSInfo ) );
- HUnlock( picsInfo );
- ReleaseResource( picsInfo );
- if ((rPICSInfo.speed >= 1) && (rPICSInfo.speed <= 60))
- infoValid = true;
- }
- }
- UseResFile(saveref);
- CloseResFile( resfile );
-
- if (!infoValid)
- {
- if (!interactive)
- rPICSInfo.speed = copyPrefsFPS();
- else if (!preferencesDialog( &rPICSInfo.speed ))
- return false; /* user canceled, so abort */
- }
- return true;
- }
-
-
- /* --------------------------------------------------------------------------------- */
-
-
- static void buildName( unsigned char * newBaseName, unsigned char * variant )
- {
- static Str63 base = "\p"; /* stores file name last used */
- static long nextNum = 1L; /* stores integer number for appending non-unique name */
- static short insertPoint = 1; /* stores location to start inserting number */
-
- unsigned char numText[12]; /* provide enough storage for largest possible long converted to string */
- short len;
-
- if (newBaseName != nil)
- {
- /* make a copy of the new base name */
- pstrcpy( base, newBaseName );
- len = (short) base[0];
-
- /* if name ends in ".PICS", insert new extension at the '.' */
- insertPoint = (!memcmpi( base+len-4, ".PICS", 5L )) ? (len-4) : (len+1);
-
- /* max file name is 31 chars, need 3 chars for ".QT" extension */
- if (insertPoint > 29)
- insertPoint = 29;
- base[insertPoint] = '.';
- base[++insertPoint] = 'Q';
- base[++insertPoint] = 'T';
- base[0] = insertPoint++; /* set length of P string, inc insert point so intserting after the 'T' */
- nextNum = 1L;
- }
- else
- {
- NumToString( nextNum++, numText );
- if ((insertPoint + numText[0]) > 32) /* 32 is proper number, even though max len is 31 */
- {
- insertPoint -= ((insertPoint + numText[0]) - 32);
- base[insertPoint-3] = '.';
- base[insertPoint-2] = 'Q';
- base[insertPoint-1] = 'T';
- }
- BlockMove( numText+1, base+insertPoint, (long) numText[0] );
- base[0] = insertPoint + numText[0] - 1;
- }
-
- /* copy new file name to output buffer */
- pstrcpy( variant, base );
- }
-